/* $Id$ */
package org.crazydays.gameplan;


import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;

import org.junit.*;
import static org.junit.Assert.*;

import static org.easymock.EasyMock.*;
import static org.easymock.classextension.EasyMock.*;

import org.crazydays.gameplan.map.IGameMap;
import org.crazydays.gameplan.model.Model;
import org.crazydays.gameplan.view.View;

/**
 * ControllerUnitTest
 */
public class ControllerUnitTest
{
    /**
     * Test constructor.
     */
    @Test
    public void testConstructor()
    {
        // mocks
        Model model = createMock(Model.class);

        // replay
        replay(model);

        // test
        Controller controller = new Controller(model);

        // verify
        verify(model);

        assertEquals("controller.model", model, controller.model);
    }

    /**
     * Test createDatabase().
     */
    @Test
    public void testCreateDatabase()
    {
        // mocks
        Model model = createMock(Model.class);

        // expect
        model.createDatabase();

        // replay
        replay(model);

        // setup
        Controller controller = new Controller(model);

        // test
        controller.createDatabase();

        // verify
        verify(model);
    }

    /**
     * Test closeDatabase().
     */
    @Test
    public void testCloseDatabase()
    {
        // mocks
        Model model = createMock(Model.class);

        // expect
        model.closeDatabase();

        // replay
        replay(model);

        // setup
        Controller controller = new Controller(model);

        // test
        controller.closeDatabase();

        // verify
        verify(model);
    }

    /**
     * Test addGameMap(IGameMap).
     */
    @Test
    public void testAddGameMap()
    {
        // mocks
        Model model = createMock(Model.class);
        IGameMap gameMap = createMock(IGameMap.class);

        // expect
        model.addGameMap(gameMap);

        // replay
        replay(model, gameMap);

        // setup
        Controller controller = new Controller(model);

        // test
        controller.addGameMap(gameMap);

        // verify
        verify(model, gameMap);
    }

    /**
     * Test openGameMap(String).
     */
    @Test
    public void testOpenGameMap()
    {
        // objects
        String name = "name";

        // mocks
        Model model = createMock(Model.class);
        IGameMap gameMap = createMock(IGameMap.class);
        View view = createMock(View.class);

        // expect
        expect(model.getGameMap(name)).andReturn(gameMap);
        view.open(gameMap);

        // replay
        replay(model, gameMap, view);

        // setup
        Controller controller = new Controller(model);
        controller.view = view;

        // test
        controller.openGameMap(name);

        // verify
        verify(model, gameMap, view);
    }

    /**
     * Test save(boolean).
     * 
     * @throws NoSuchMethodException
     * @throws SecurityException
     */
    @Test
    public void testSave_saveas_badprompt()
        throws SecurityException, NoSuchMethodException
    {
        // mock
        Controller controller =
            createMock(Controller.class, new Method[] { Controller.class
                .getDeclaredMethod("promptForSaveFile") });
        Model model = createMock(Model.class);

        // expect
        expect(controller.promptForSaveFile()).andReturn(false);

        // replay
        replay(controller, model);

        // test
        controller.save(true);

        // verify
        verify(controller, model);
    }

    /**
     * Test save(boolean).
     * 
     * @throws NoSuchMethodException
     * @throws SecurityException
     * @throws IOException
     */
    @Test
    public void testSave_saveas()
        throws SecurityException, NoSuchMethodException, IOException
    {
        // mock
        Controller controller =
            createMock(Controller.class, new Method[] { Controller.class
                .getDeclaredMethod("promptForSaveFile") });
        Model model = createMock(Model.class);

        // expect
        expect(controller.promptForSaveFile()).andReturn(true);
        model.save();

        // setup
        controller.model = model;

        // replay
        replay(controller, model);

        // test
        controller.save(true);

        // verify
        verify(controller, model);
    }

    /**
     * Test save(boolean).
     * 
     * @throws NoSuchMethodException
     * @throws SecurityException
     * @throws IOException
     */
    @Test
    public void testSave_save()
        throws SecurityException, NoSuchMethodException, IOException
    {
        // mock
        Controller controller =
            createMock(Controller.class, new Method[] { Controller.class
                .getDeclaredMethod("promptForSaveFile") });
        Model model = createMock(Model.class);

        // expect
        expect(model.isSaveFileSet()).andReturn(false);
        expect(controller.promptForSaveFile()).andReturn(true);
        model.save();

        // setup
        controller.model = model;

        // replay
        replay(controller, model);

        // test
        controller.save(false);

        // verify
        verify(controller, model);
    }

    /**
     * Test openDatabase().
     * 
     * @throws SecurityException
     * @throws NoSuchMethodException
     * @throws IOException
     */
    @Test
    public void testOpenDatabase()
        throws SecurityException, NoSuchMethodException, IOException
    {
        // objects
        File file = new File(".");

        // mocks
        Controller controller =
            createMock(Controller.class, new Method[] { Controller.class
                .getDeclaredMethod("promptForOpenFile") });
        Model model = createMock(Model.class);

        // expect
        expect(controller.promptForOpenFile()).andReturn(file);
        model.openDatabase(file);

        // replay
        replay(controller, model);

        // setup
        controller.model = model;

        // test
        controller.openDatabase();

        // verify
        verify(controller, model);
    }

    /**
     * Test toggleGrid().
     */
    @Test
    public void testToggleGrid()
    {
        // mocks
        Model model = createMock(Model.class);
        View view = createMock(View.class);

        // setup
        Controller controller = new Controller(model);
        controller.view = view;

        // expect
        expect(view.toggleGrid()).andReturn(true);

        // replay
        replay(model, view);

        // test
        boolean result = controller.toggleGrid();

        // verify
        verify(model, view);

        assertEquals("result", true, result);
    }
}
